package com.atguigu.gulimall.product.service.impl;

import com.atguigu.common.utils.R;
import com.atguigu.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.atguigu.gulimall.product.dao.AttrDao;
import com.atguigu.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.atguigu.gulimall.product.entity.AttrEntity;
import com.atguigu.gulimall.product.vo.AttrAttrGroupRelationDeleteVo;
import com.atguigu.gulimall.product.vo.AttrGroupWithAttrsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.AttrGroupDao;
import com.atguigu.gulimall.product.entity.AttrGroupEntity;
import com.atguigu.gulimall.product.service.AttrGroupService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private AttrDao attrDao;

    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catelogId) {
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        if (catelogId != 0) {
            wrapper.eq("catelog_id", catelogId);
        }
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.eq("attr_group_id", key).or().eq("attr_group_name", key);
        }
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public List<AttrEntity> getAllAttrByAttrGroup(Long attrgroupId) {
//        获取属性分组的关联的所有属性
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationDao.
                selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId));
        // 提取attrid,获取详细信息
        List<Long> attrIdList = attrAttrgroupRelationEntities.stream().
                map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        if (attrIdList.isEmpty()) return null;
        return attrDao.selectBatchIds(attrIdList);
    }

    @Transactional
    @Override
    public void deleteBatch(AttrAttrGroupRelationDeleteVo[] deleteVo) {
        attrAttrgroupRelationDao.deleteBatch(deleteVo);
    }

    @Override
    public PageUtils getAttrNoRelation(Long attrgroupId, Map<String, Object> params) {
        AttrGroupEntity attrGroupEntity = this.getById(attrgroupId);
        if (attrGroupEntity != null) {
            // 获取分组的所属分类id
            Long catelogId = attrGroupEntity.getCatelogId();
            // 查出同一分类下的分组
            List<AttrGroupEntity> groupEntities = this.list(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
            List<Long> attrGroupIds = groupEntities.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toList());
            // 查出关系中被其他分组选走的属性
            List<AttrAttrgroupRelationEntity> attrIds = attrAttrgroupRelationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .in("attr_group_id", attrGroupIds));
            // 查询 1.同一个分类 2.未被选择的 3.规格参数(attr_type = 1)
            QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("catelog_id", catelogId).eq("attr_type", 1);
            if (attrIds != null && !attrIds.isEmpty()) {
                wrapper.notIn("attr_id", attrIds);
            }
            String key = (String) params.get("key");
            if (!StringUtils.isEmpty(key)) {
                wrapper.and((w)->{
                    w.eq("attr_id", key).or().like("attr_name", key);
                });
            }
            IPage<AttrEntity> page = attrDao.selectPage(
                    new Query<AttrEntity>().getPage(params),
                    wrapper
            );
            return new PageUtils(page);
        }
        return null;
    }

    @Override
    public List<AttrGroupWithAttrsVo> getAttrGroupWithAttrs(Long catelogId) {
        // 获取同一分类下的分组
        List<AttrGroupEntity> attrGroupEntities = this.list(new QueryWrapper<AttrGroupEntity>()
                        .eq("catelog_id", catelogId));
        // 获取分组下的属性
        if (attrGroupEntities != null && !attrGroupEntities.isEmpty()) {
            return attrGroupEntities.stream().map((item) -> {
                AttrGroupWithAttrsVo attrGroupWithAttrsVo = new AttrGroupWithAttrsVo();
                BeanUtils.copyProperties(item, attrGroupWithAttrsVo);
                // 通过关系表获取属性
                List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationDao
                        .selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                        .eq("attr_group_id", item.getAttrGroupId()));
                if (attrAttrgroupRelationEntities != null && !attrAttrgroupRelationEntities.isEmpty()) {
                    List<Long> attrIds = attrAttrgroupRelationEntities.stream()
                            .map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
                    List<AttrEntity> attrEntityList = attrDao.selectBatchIds(attrIds);
                    attrGroupWithAttrsVo.setAttrs(attrEntityList);
                }
                return attrGroupWithAttrsVo;
            }).collect(Collectors.toList());
        }
        return null;
    }

}